#include "font.h"


CFont::CFont(string szFaceName, string szPath, int nSize)
    : m_pFont(nullptr),
    m_szFontPath(string("resources\\fonts\\") + szPath)
{
    /**
     * Create a new font object. This will attempt to load the font from
     * the resources/fonts folder and create the font object.
     *
     * @param string szFaceName The name of the face this font represents; e.g.
     *  "bomberman".
     * @param string szPath The path to the font (from resources/fonts), e.g.
     *  "bm.tff"
     */

    int nAmount(AddFontResource(m_szFontPath.c_str()));

    if (! nAmount)
    {
        MessageBox(NULL, 
            (string("Failed to add font at Path: ") + m_szFontPath).c_str(),
            "CFont::CFont()", MB_OK);
    }

    LOGFONT Font = {
        nSize, 0,            // Height and width
        0,                   // Escapement, angle of text parallel to x axis
        0,                   // Orientation, escapement step for each character
        FW_MEDIUM,           // Font weight
        false,               // Italic?
        false,               // Underline?
        false,               // Strike out?
        DEFAULT_CHARSET,     // The character set
        OUT_DEFAULT_PRECIS,  // How closely to match our values
        CLIP_DEFAULT_PRECIS, // How to clip if it goes outside the region
        DEFAULT_QUALITY,     // Quality of text
        DEFAULT_PITCH |      // The pitch and family of the font
        FF_DONTCARE       
    };

    // Copy the face name into the font object
    strcpy(Font.lfFaceName, szFaceName.c_str());
    //strcpy(Font.lfFaceName, TEXT("Arial"));

    LPDIRECT3DDEVICE9 pDevice(CDeviceManager::getInstance()->getDevice());

    if (D3DXCreateFont(
        pDevice,                // Direct 3D device
        Font.lfHeight,          // Height of font
        Font.lfWidth,           // Width of font
        Font.lfWeight,          // Weight of font
        0,                      // Mip Levels
        Font.lfItalic,          // Italic?
        Font.lfCharSet,         // Character set
        Font.lfOutPrecision,    // Precision to output the text
        Font.lfQuality,         // The quality of the text
        Font.lfPitchAndFamily,  // The pitch and family name
        Font.lfFaceName,        // The face name
        &m_pFont)               // Address to store the font
        != S_OK)
    {
        MessageBox(NULL, 
            (string("Failed to create font: ") + szFaceName).c_str(),
            "CFont::CFont()", MB_OK);
    }
}

CFont::~CFont()
{
    /** 
     * Font's destructor, clear up the memory for the font
     */
    RemoveFontResource(m_szFontPath.c_str());

    if (m_pFont != nullptr)
    {
        m_pFont->Release();
    }
}

void CFont::drawText(CUISprite *pSprite, string szText,
        int nX, int nY,
        D3DCOLOR color)
{
    /**
     * Draws text in a given sprite at a particular position. There is no
     * right or bottom clipping on this text, as the clipping window will be
     * defined as the whole screen.
     *
     * @param CSprite *pSprite The sprite to draw the text on
     * @param string szText The text to draw to the screen
     * @param int nX The X position to draw the text at
     * @param int nY The Y position to draw the text at
     * @param OPTIONAL D3DXCOLOR color A specific colour to draw the text in
     */
    RECT rect;
    rect.bottom = Constants::WINDOW_HEIGHT;
    rect.right = Constants::WINDOW_WIDTH;
    rect.left = nX;
    rect.top = nY;

    if (m_pFont != nullptr)
    {
        pSprite->getSprite()->Begin(D3DXSPRITE_ALPHABLEND);
        m_pFont->DrawText(pSprite->getSprite(), szText.c_str(), szText.length(), 
            &rect, 0, color);
        pSprite->getSprite()->End();
    }
}

void CFont::drawText(string szText, int nX, int nY, D3DCOLOR color)
{
    /**
     * Draws some text to the screen at a given position. There is no
     * right or bottom clipping on this text, as the clipping window will be
     * defined as the whole screen.
     *
     * @param string szText The text to draw to the screen
     * @param int nX The X position to draw the text at
     * @param int nY The Y position to draw the text at
     * @param OPTIONAL D3DXCOLOR color A specific colour to draw the text in
     */
    RECT rect;
    rect.bottom = Constants::WINDOW_HEIGHT;
    rect.right = Constants::WINDOW_WIDTH;
    rect.left = nX;
    rect.top = nY;

    if (m_pFont != nullptr)
    {
        m_pFont->DrawText(nullptr, szText.c_str(), szText.length(), &rect,
            0, color);
    }
}

void CFont::drawText(CUISprite *pSprite, string szText, LPRECT pRect, 
    D3DCOLOR color)
{
    /**
     * Draws text in a given sprite at a particular position.
     *
     * @param CSprite *pSprite The sprite to draw the text on
     * @param string szText The text to draw to the screen
     * @param LPRECT pRect The RECT area defining the start position and
     *  clipping region of the text.
     * @param OPTIONAL D3DXCOLOR color A specific colour to draw the text in
     */

    if (m_pFont != nullptr)
    {
        pSprite->getSprite()->Begin(D3DXSPRITE_ALPHABLEND);
        m_pFont->DrawText(pSprite->getSprite(), szText.c_str(), szText.length(), 
            pRect, 0, color);
        pSprite->getSprite()->End();
    }
}

void CFont::drawText(string szText, LPRECT pRect, D3DCOLOR color)
{
    /**
     * Draws some text to the screen at a given position. 
     *
     * @param string szText The text to draw to the screen
     * @param LPRECT pRect The RECT area defining the start position and
     *  clipping region of the text.
     * @param OPTIONAL D3DXCOLOR color A specific colour to draw the text in
     */

    if (m_pFont != nullptr)
    {
        m_pFont->DrawText(nullptr, szText.c_str(), szText.length(), pRect,
            0, color);
    }
}